package com.phychips.rcp;

public class RCPCommandBuilder {
	private byte[] RCPCmdPacket;

	public byte[] RCPCommand(byte Code, byte[] payload) {
		return RCPCommand(Code, payload, payload.length);
	}

	public byte[] RCPCommand(byte Code, byte[] payload, int payload_length) {
		RCPCmdPacket = new byte[payload_length + 8];

		UserCommandBuild(Code, payload, payload_length);

		AppendCRC();

		return RCPCmdPacket;
	}

	private void UserCommandBuild(byte Code, byte[] payload, int payload_length) {
		// byte[] temp = new byte[payload_length + 6];
		RCPCmdPacket[0] = (byte) RcpConst.PREAMBLE;
		RCPCmdPacket[1] = (byte) RcpConst.HEADER_CMD;
		RCPCmdPacket[2] = Code;
		RCPCmdPacket[3] = (byte) ((payload_length >>> 8) & 0xFF);
		RCPCmdPacket[4] = (byte) ((payload_length >>> 0) & 0xFF);
		if (payload != null) {
			System.arraycopy(payload, 0, RCPCmdPacket, 5, payload_length);
		}
		RCPCmdPacket[5 + payload_length] = (byte) RcpConst.ENDMARK;
	} // End getUserCommand()

	private void AppendCRC() {
		// byte[] temp = new byte[RCPCommand_length + 2];
		int CRC = CRCCalculator
				.Cal_CRC16(RCPCmdPacket, RCPCmdPacket.length - 2);

		RCPCmdPacket[RCPCmdPacket.length - 2] = (byte) ((CRC >>> 8) & 0xFF);
		RCPCmdPacket[RCPCmdPacket.length - 1] = (byte) ((CRC >>> 0) & 0xFF);
	} // End AppendHeader()

	public byte[] ReaderInformationCmd(byte type) {
		byte[] temp = new byte[1];
		temp[0] = type;
		return RCPCommand((byte) RcpConst.RCP_CMD_GET_RD_INFO, temp,
				temp.length);
	}

	public byte[] RegionCmd() {
		return RCPCommand((byte) RcpConst.RCP_CMD_GET_REGION, null, 0);
	}

	public byte[] RegionCmd(byte region) {
		byte[] temp = new byte[1];
		temp[0] = region;
		return RCPCommand((byte) RcpConst.RCP_CMD_SET_REGION, temp,
				temp.length);
	}

	public byte[] StartAutoRead(int repeat) {
		byte[] temp = new byte[3];
		temp[0] = (byte) 0x02;
		temp[1] = (byte) ((repeat >>> 8) & 0xFF);
		temp[2] = (byte) ((repeat >>> 0) & 0xFF);
		return RCPCommand((byte) RcpConst.RCP_CMD_STRT_AUTO_READ, temp,
				temp.length);
	}

	public byte[] StopAutoRead() {
		return RCPCommand((byte) RcpConst.RCP_CMD_STOP_AUTO_READ, null, 0);
	}

	public byte[] StartAutoRead2(byte NofTag, byte elapsed_time, int repeat) {
		byte[] temp = new byte[5];
		// 0x01 : type B, 0x02 : type C
		temp[0] = (byte) 0x02;
		temp[1] = NofTag;
		temp[2] = elapsed_time;
		temp[3] = (byte) ((repeat >>> 8) & 0xFF);
		temp[4] = (byte) ((repeat >>> 0) & 0xFF);
		return RCPCommand((byte) 0x36, temp, temp.length);
	}

	public byte[] StopAutoRead2() {
		byte[] temp = { 0x00 };
		return RCPCommand((byte) 0x37, temp, 0);
	}

	public byte[] Loopback() {
		final byte loopbackPayload = (byte) 0xAA;
		byte[] temp = new byte[20];

		for (int i = 0; i < temp.length; i++) {
			temp[i] = (byte) loopbackPayload;
		}

		// loopbackPayload++;

		return RCPCommand((byte) 0xAC, temp, temp.length);
	}

	public byte[] AudioTone(int data) {
		byte[] temp = new byte[2];

		temp[0] = (byte) (0xff); // test mode
		temp[1] = (byte) (data & 0xff);

		return RCPCommand((byte) 0xAE, temp, temp.length);
	}

	public byte[] Fer() {
		return RCPCommand((byte) 0xAD, null, 0);
	}
}
